package com.partners.component.resolver;

import com.alibaba.fastjson.JSONObject;
import com.partners.annotation.SimpleParam;
import com.partners.constant.ErrorMessageEnum;
import com.partners.model.BusinessException;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Parameter;

/**
 * 简单参数解析器
 * 参数解析器3
 * @author forever
 * @date 2018/7/6 14:48
 */
public class SimpleParamResolver implements HandlerMethodArgumentResolver {

    /**
     * 判断Resolver是否支持该参数
     * @param methodParameter 方法参数
     * @return boolean true为支持
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        Parameter param = methodParameter.getParameter();
        return param.getDeclaredAnnotation(SimpleParam.class) != null;

    }

    /**
     * 参数转换
     * @param methodParameter 方法参数
     * @param modelAndViewContainer model容器
     * @param nativeWebRequest 与HttpServletRequest相关
     * @param webDataBinderFactory 数据绑定相关
     * @return 转换后的对象
     */
    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory){

        // 获取注解上的值
        String parameterName = methodParameter.getParameter().getDeclaredAnnotation(SimpleParam.class).value();

        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);

        try {
            // 将body字符串转化为json，然后从json中获取key = parameterName的值
            StringBuilder bodyStrBuilder = new StringBuilder();
            ServletInputStream is = request.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            String line;
            while ((line = reader.readLine()) != null) {
                bodyStrBuilder.append(line);
            }

            String bodyStr = bodyStrBuilder.toString();

            Parameter parameter = methodParameter.getParameter();
            JSONObject json = JSONObject.parseObject(bodyStr);
            if(json == null) {
                return null;
            }
            return json.getObject(parameterName, parameter.getType());

        }catch (IOException e) {
            throw BusinessException.of(ErrorMessageEnum.PARAMETER_ERROR);
        }
    }
}
